package controller

import (
	"fmt"
	"net/http"

	"gitee.com/ysl729895/go-mall/internal/model"
	"gitee.com/ysl729895/go-mall/internal/service"
	"github.com/gin-gonic/gin"
)

type UserController struct {
	service service.UserService
}

func NewUserController(service service.UserService) *UserController {
	return &UserController{service: service}
}

// RegisterRequest 注册请求结构
type RegisterRequest struct {
	Username string `json:"username" binding:"required,min=3,max=20" example:"testuser"`    // 用户名
	Password string `json:"password" binding:"required,min=6,max=20" example:"password123"` // 密码
}

// LoginRequest 登录请求结构
type LoginRequest struct {
	Username string `json:"username" binding:"required" example:"testuser"`    // 用户名
	Password string `json:"password" binding:"required" example:"password123"` // 密码
}

// Register 用户注册
// @Summary 用户注册
// @Description 注册新用户
// @Tags 用户管理
// @Accept json
// @Produce json
// @Param request body RegisterRequest true "注册信息"
// @Success 201 {object} model.User "注册成功"
// @Failure 400 {object} string "请求参数错误"
// @Router /api/register [post]
func (c *UserController) Register(ctx *gin.Context) {
	var req RegisterRequest
	if err := ctx.ShouldBindJSON(&req); err != nil {
		ctx.AbortWithStatusJSON(http.StatusBadRequest, model.ErrorResponse{
			Code:    http.StatusBadRequest,
			Message: "请求参数格式不正确",
			Error:   err.Error(),
		})
		return
	}

	user, err := c.service.Register(req.Username, req.Password)
	if err != nil {
		ctx.AbortWithStatusJSON(http.StatusBadRequest, model.ErrorResponse{
			Code:    http.StatusBadRequest,
			Message: "用户注册失败",
			Error:   err.Error(),
		})
		return
	}

	ctx.Set("responseData", user)
	ctx.Set("responseMessage", "注册成功")
	ctx.Status(http.StatusCreated)
}

// Login 用户登录
// @Summary 用户登录
// @Description 用户登录获取token
// @Tags 用户管理
// @Accept json
// @Produce json
// @Param request body LoginRequest true "登录信息"
// @Success 200 {object} string "登录成功"
// @Failure 400 {object} string "请求参数错误"
// @Failure 401 {object} string "用户名或密码错误"
// @Router /api/login [post]
func (c *UserController) Login(ctx *gin.Context) {
	var req LoginRequest
	if err := ctx.ShouldBindJSON(&req); err != nil {
		ctx.AbortWithStatusJSON(http.StatusBadRequest, model.ErrorResponse{
			Code:    http.StatusBadRequest,
			Message: "登录请求参数格式不正确",
			Error:   err.Error(),
		})
		return
	}

	resp, err := c.service.Login(req.Username, req.Password)
	if err != nil {
		ctx.AbortWithStatusJSON(http.StatusUnauthorized, model.ErrorResponse{
			Code:    http.StatusUnauthorized,
			Message: "用户名或密码错误",
			Error:   "认证失败，请检查用户名和密码",
		})
		return
	}

	ctx.Set("responseData", resp)
	ctx.Set("responseMessage", "登录成功")
}

// UserInfoRequest 用户信息请求
type UserInfoRequest struct {
	Username string `json:"username" example:"testuser"` // 用户名
}

// GetUserInfo 获取用户信息
// @Summary 获取用户信息
// @Description 获取当前登录用户信息
// @Tags 用户管理
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param request body UserInfoRequest true "用户信息请求"
// @Success 200 {object} model.User "用户信息"
// @Failure 401 {object} string "未授权"
// @Router /api/user/info [get]
func (c *UserController) GetUserInfo(ctx *gin.Context) {
	userID := ctx.GetUint("user_id")
	fmt.Println(userID)
	if userID == 0 {
		ctx.AbortWithStatusJSON(http.StatusUnauthorized, model.ErrorResponse{
			Code:    http.StatusUnauthorized,
			Message: "未授权，请先登录",
		})
		return
	}
	user, err := c.service.GetUserInfoByID(userID)
	fmt.Println(user)
	if err != nil {
		ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.ErrorResponse{
			Code:    http.StatusInternalServerError,
			Message: "获取用户信息失败",
			Error:   err.Error(),
		})
		return
	}
	ctx.Set("responseData", user)
	ctx.Set("responseMessage", "获取用户信息成功")
}

// UpdateUserRequest 更新用户请求
type UpdateUserRequest struct {
	Email string `json:"email" binding:"required,email" example:"user@example.com"` // 邮箱
}

// UpdateUserInfo 更新用户信息
// @Summary 更新用户信息
// @Description 更新当前登录用户信息
// @Tags 用户管理
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param request body UpdateUserRequest true "更新信息"
// @Success 200 {object} model.User "更新后的用户信息"
// @Failure 400 {object} string "请求参数错误"
// @Router /api/user/update [put]
func (c *UserController) UpdateUserInfo(ctx *gin.Context) {
	var req UpdateUserRequest
	if err := ctx.ShouldBindJSON(&req); err != nil {
		ctx.AbortWithStatusJSON(http.StatusBadRequest, model.ErrorResponse{
			Code:    http.StatusBadRequest,
			Message: "请求参数格式不正确",
			Error:   err.Error(),
		})
		return
	}

	username := ctx.GetString("username")
	user, err := c.service.UpdateUserInfo(username, req.Email)
	if err != nil {
		ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.ErrorResponse{
			Code:    http.StatusInternalServerError,
			Message: "更新用户信息失败",
			Error:   err.Error(),
		})
		return
	}

	ctx.Set("responseData", user)
	ctx.Set("responseMessage", "修改成功")
}

// ChangePasswordRequest 修改密码请求
type ChangePasswordRequest struct {
	OldPassword string `json:"oldPassword" binding:"required" example:"oldpassword123"`              // 旧密码
	NewPassword string `json:"newPassword" binding:"required,min=6,max=20" example:"newpassword123"` // 新密码
}

// ChangePassword 修改密码
// @Summary 修改密码
// @Description 修改当前登录用户密码
// @Tags 用户管理
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Param request body ChangePasswordRequest true "密码修改信息"
// @Success 200 {object} string "修改成功"
// @Failure 400 {object} string "请求参数错误"
// @Failure 401 {object} string "旧密码不正确"
// @Router /api/user/change-password [put]
func (c *UserController) ChangePassword(ctx *gin.Context) {
	var req ChangePasswordRequest
	if err := ctx.ShouldBindJSON(&req); err != nil {
		ctx.AbortWithStatusJSON(http.StatusBadRequest, model.ErrorResponse{
			Code:    http.StatusBadRequest,
			Message: "请求参数格式不正确",
			Error:   err.Error(),
		})
		return
	}

	username := ctx.GetString("username")
	err := c.service.ChangePassword(username, req.OldPassword, req.NewPassword)
	if err != nil {
		ctx.AbortWithStatusJSON(http.StatusUnauthorized, model.ErrorResponse{
			Code:    http.StatusUnauthorized,
			Message: "修改密码失败",
			Error:   err.Error(),
		})
		return
	}

	ctx.Set("responseData", "密码修改成功")
	ctx.Set("responseMessage", "密码修改成功")
}

// Logout 用户退出
// @Summary 用户退出
// @Description 用户退出登录
// @Tags 用户管理
// @Accept json
// @Produce json
// @Security ApiKeyAuth
// @Success 200 {object} string "退出成功"
// @Router /api/user/logout [post]
func (c *UserController) Logout(ctx *gin.Context) {
	// 实际注销逻辑可能在中间件中处理
	ctx.Set("responseData", "退出成功")
	ctx.Set("responseMessage", "退出成功")
}
